package org.wikinews.en.wikinewsreader;


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.ByteArrayBuffer;

import android.os.Handler;
import android.util.Log;

public class NetTrick {
	private static String result = "";
	private static final String TAG = "WikinewsReader" ;

	public static String doIt(String[][] sending, Handler handler) {
		Log.d(TAG,"NetTrick.doIt()");
		result = ""; // If we don't zero out res here, it is possible that on error,
					 // it could return the same data as last time, again.
		String androidID = WikinewsReader.getAndroidID();
		if(androidID == null){
			androidID = "00000";
		}
		
		// Create a new HttpClient and Post Header  
		HttpParams httpParam = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParam, 30000);
		HttpConnectionParams.setSoTimeout(httpParam, 15000);
		HttpClient httpclient = new DefaultHttpClient(httpParam);  
		
		
		// Sample compression docs from: http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientGZipContentCompression.java

		/*
		 * Handles telling the server we can accept gzip
		 */
		((AbstractHttpClient) httpclient).addRequestInterceptor(new HttpRequestInterceptor() {
			
			public void process(
                    final HttpRequest request, 
                    final HttpContext context) throws HttpException, IOException {
                if (!request.containsHeader("Accept-Encoding")) {
                    request.addHeader("Accept-Encoding", "gzip");
                }
            }
        });

		/*
		 * Handles receiving the gzip'd content and what to do with it
		 */
        ((AbstractHttpClient) httpclient).addResponseInterceptor(new HttpResponseInterceptor() {
            
            public void process(
                    final HttpResponse response, 
                    final HttpContext context) throws HttpException, IOException {
                HttpEntity entity = response.getEntity();
                Header ceheader = entity.getContentEncoding();
                if (ceheader != null) {
                    HeaderElement[] codecs = ceheader.getElements();
                    for (int i = 0; i < codecs.length; i++) {
                        if (codecs[i].getName().equalsIgnoreCase("gzip")) {
                            response.setEntity(
                                    new GzipDecompressingEntity(response.getEntity())); 
                            return;
                        }
                    }
                }
            }
            
        });

		HttpPost httppost = new HttpPost("http://seawulf.com/reader/");

		try {  
			// Add your data  
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			for(String[] a : sending){
				//Log.d(TAG, "Adding pair: "+a[0]+" == "+a[1]);
				nameValuePairs.add(new BasicNameValuePair(a[0], a[1]));
			}
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));  
			
			//String ver = WikinewsReader.getVerison();
			String ver = WikinewsReader.getVersionName();
			httppost.setHeader("User-Agent", "Mozilla/5.0 (WikinewsReader; Android; " +ver+"; ID"+androidID+")");
			// Execute HTTP Post Request  
			HttpResponse response = httpclient.execute(httppost);
			 
			InputStream is = response.getEntity().getContent();
			BufferedInputStream bis = new BufferedInputStream(is);
			ByteArrayBuffer baf = new ByteArrayBuffer(20);
			
			int current = 0;  
			while((current = bis.read()) != -1){  
				baf.append((byte)current);  
			}  
			   
			/* Convert the Bytes read to a String. */  
			result = new String(baf.toByteArray());
			
			Log.d(TAG,"Result from webserver: " + result);
		} catch (ClientProtocolException e) {  
			handler.sendEmptyMessage(14);
		} catch (UnknownHostException e) {
			handler.sendEmptyMessage(15);
		} catch (IOException e) {  
			handler.sendEmptyMessage(16);
		} catch (Exception e) {
        	Log.e(TAG,"General Exception");
        	Log.e(TAG, e.getMessage().toString());
        	handler.sendEmptyMessage(11);
		}
		return result;
	}
	
	/*
	 * Does the actual decompression
	 */
    static class GzipDecompressingEntity extends HttpEntityWrapper {

        public GzipDecompressingEntity(final HttpEntity entity) {
            super(entity);
        }
    
        @Override
        public InputStream getContent()
            throws IOException, IllegalStateException {

            // the wrapped entity's getContent() decides about repeatability
            InputStream wrappedin = wrappedEntity.getContent();

            return new GZIPInputStream(wrappedin);
        }

        @Override
        public long getContentLength() {
            // length of ungzipped content is not known
            return -1;
        }

    } 
    

}